﻿/*****************************************************
 * 本类库的核心系 JNTemplate
 * (C) JNTemplate 2011
 * 作者：翅膀的初衷 QQ:4585839
 * 网址：http://www.JiNianNet.com
 *****************************************************/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
using System.Web;
using System.Globalization;

namespace JinianNet.JNTemplate.Process
{
    public class VariableScope
    {
        private VariableScope _parent;
        //private IDataExecution _dataExecution;
        private bool enableCaching;
        private static readonly char[] expressionPartSeparator;
        private static readonly char[] indexExprEndChars;
        private static readonly char[] indexExprStartChars;
        private Dictionary<string, object> _values;
        private Dictionary<string, object> _cacheDictionary;

        public bool EnableCaching
        {
            get
            {
                return enableCaching;
            }
            set
            {
                enableCaching = value;
            }
        }

        //private static readonly ConcurrentDictionary<Type, PropertyDescriptorCollection> propertyCache;//Concurrent

        public VariableScope()
            : this(null, true)
        {

        }

        public VariableScope(VariableScope parent)
            : this(null, true)
        {

        }

        public VariableScope(VariableScope parent,  bool enableCaching)
        {
            this._parent = parent;
            this._values = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
            this._cacheDictionary = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
            //this._dataExecution = dataExecution;
            this.enableCaching = enableCaching;
        }


        static VariableScope()
        {
            expressionPartSeparator = new char[] { '.' };
            indexExprStartChars = new char[] { '[', '(' };
            indexExprEndChars = new char[] { ']', ')' };
            //propertyCache = new ConcurrentDictionary<Type, PropertyDescriptorCollection>();

        }


        /// <summary>
        /// 
        /// </summary>
        public void Clear(bool all)
        {
            this._values.Clear();
            this._cacheDictionary.Clear();
            if (all)
            {
                if (this._parent != null)
                {
                    this._parent.Clear(all);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public VariableScope Parent
        {
            get { return this._parent; }
        }

        /// <summary>
        /// 
        /// </summary>
        public bool IsDefined(string name)
        {
            if (this._values.ContainsKey(name))
                return true;
            else if (_parent != null)
                return this._parent.IsDefined(name);
            else
                return false;
        }
        /// <summary>
        /// 
        /// </summary>
        public object this[string name]
        {
            get
            {
                object val;
                if (this._values.TryGetValue(name, out val))
                    return val;
                if (this._parent != null)
                    return this._parent[name];
                return null;
            }
            set
            {
                this._values[name] = value;
            }
        }

        public VariableScope Copy()
        {
            VariableScope owen = new VariableScope(this.Parent,this.EnableCaching);
            foreach (KeyValuePair<string, object> value in this._values)
            {
                owen[value.Key] = value.Value;
            }
            return owen;
        }
        #region EVAL解析
        public object Eval(string expression)
        {
            if (expression == null)
            {
                return null;
            }
            expression = expression.Trim();
            if (expression.Length == 0)
            {
                return null;
            }

            object value = null;

            if (EnableCaching)
            {
                if (this._cacheDictionary.TryGetValue(expression, out value))
                    return value;
            }

            string[] expressionParts = expression.Split(expressionPartSeparator);
            if (expressionParts.Length > 0)
            {
                if (expressionParts[0].IndexOfAny(indexExprStartChars) < 0)
                {
                    string[] array;
                    if (expressionParts.Length > 1)
                    {
                        array = new string[expressionParts.Length - 1];
                        Array.Copy(expressionParts, 1, array, 0, array.Length);
                    }
                    else
                    {
                        array = new string[0];
                    }
                    value = Eval(this[expressionParts[0]], array);
                }
                else
                {
                    int length = expressionParts[0].IndexOfAny(indexExprStartChars);
                    if (length < 0)
                    {
                        throw new ArgumentException("DataBinder_Invalid_Indexed_Expr");//SR.GetString("DataBinder_Invalid_Indexed_Expr", new object[] { expr }));
                    }
                    if (length != 0)
                    {
                        value = this[expressionParts[0].Substring(0, length).Trim()];
                        expressionParts[0] = expressionParts[0].Substring(length, (expressionParts[0].Length - length));
                        value = Eval(value, expressionParts);
                    }
                    else
                    {
                        value = Eval(this, expressionParts);
                    }
                }

            }
            if (EnableCaching)
            {
                this._cacheDictionary[expression] = value;
            }
            return value;
        }

        //public static object GetIndexedPropertyValue(object container, string expr)
        //{
        //    if (container == null)
        //    {
        //        throw new ArgumentNullException("container");
        //    }
        //    if (string.IsNullOrEmpty(expr))
        //    {
        //        throw new ArgumentNullException("expr");
        //    }
        //    object obj2 = null;
        //    bool flag = false;
        //    int length = expr.IndexOfAny(indexExprStartChars);
        //    int num2 = expr.IndexOfAny(indexExprEndChars, length + 1);
        //    if (((length < 0) || (num2 < 0)) || (num2 == (length + 1)))
        //    {
        //        throw new ArgumentException("DataBinder_Invalid_Indexed_Expr");//SR.GetString("DataBinder_Invalid_Indexed_Expr", new object[] { expr }));
        //    }
        //    string propName = null;
        //    object obj3 = null;
        //    string s = expr.Substring(length + 1, (num2 - length) - 1).Trim();
        //    if (length != 0)
        //    {
        //        propName = expr.Substring(0, length);
        //    }
        //    if (s.Length != 0)
        //    {
        //        if (((s[0] == '"') && (s[s.Length - 1] == '"')) || ((s[0] == '\'') && (s[s.Length - 1] == '\'')))
        //        {
        //            obj3 = s.Substring(1, s.Length - 2);
        //        }
        //        else if (char.IsDigit(s[0]))
        //        {
        //            int num3;
        //            flag = int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out num3);
        //            if (flag)
        //            {
        //                obj3 = num3;
        //            }
        //            else
        //            {
        //                obj3 = s;
        //            }
        //        }
        //        else
        //        {
        //            obj3 = s;
        //        }
        //    }
        //    if (obj3 == null)
        //    {
        //        throw new ArgumentException("DataBinder_Invalid_Indexed_Expr");//SR.GetString("DataBinder_Invalid_Indexed_Expr", new object[] { expr }));
        //    }
        //    object propertyValue = null;
        //    if ((propName != null) && (propName.Length != 0))
        //    {
        //        propertyValue = GetPropertyValue(container, propName);
        //    }
        //    else
        //    {
        //        propertyValue = container;
        //    }
        //    if (propertyValue == null)
        //    {
        //        return obj2;
        //    }
        //    Array array = propertyValue as Array;
        //    if ((array != null) && flag)
        //    {
        //        return array.GetValue((int)obj3);
        //    }
        //    if ((propertyValue is IList) && flag)
        //    {
        //        return ((IList)propertyValue)[(int)obj3];
        //    }
        //    PropertyInfo info = propertyValue.GetType().GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, null, new Type[] { obj3.GetType() }, null);
        //    if (info == null)
        //    {
        //        throw new ArgumentException("DataBinder_No_Indexed_Accessor");//SR.GetString("DataBinder_No_Indexed_Accessor", new object[] { propertyValue.GetType().FullName }));
        //    }
        //    return info.GetValue(propertyValue, new object[] { obj3 });
        //}


        #region 4.0版本

        public static object GetIndexedPropertyValue(object container, string expr)
        {
            if (container == null)
            {
                return null;
                //throw new ArgumentNullException("container");
            }
            if (string.IsNullOrEmpty(expr))
            {
                return null;
                //throw new ArgumentNullException("expr");
            }
            object obj2 = null;
            bool flag = false;
            int length = expr.IndexOfAny(indexExprStartChars);
            int num2 = expr.IndexOfAny(indexExprEndChars, length + 1);
            if (((length < 0) || (num2 < 0)) || (num2 == (length + 1)))
            {
                return null;
                //throw new ArgumentException("DataBinder_Invalid_Indexed_Expr");//SR.GetString("DataBinder_Invalid_Indexed_Expr", new object[] { expr }));
            }
            string propName = null;
            object obj3 = null;
            string s = expr.Substring(length + 1, (num2 - length) - 1).Trim();
            if (length != 0)
            {
                propName = expr.Substring(0, length);
            }
            if (s.Length != 0)
            {
                if (((s[0] == '"') && (s[s.Length - 1] == '"')) || ((s[0] == '\'') && (s[s.Length - 1] == '\'')))
                {
                    obj3 = s.Substring(1, s.Length - 2);
                }
                else if (char.IsDigit(s[0]))
                {
                    int num3;
                    flag = int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out num3);
                    if (flag)
                    {
                        obj3 = num3;
                    }
                    else
                    {
                        obj3 = s;
                    }
                }
                else
                {
                    obj3 = s;
                }
            }
            if (obj3 == null)
            {
                return null;
                //throw new ArgumentException("DataBinder_Invalid_Indexed_Expr");//SR.GetString("DataBinder_Invalid_Indexed_Expr", new object[] { expr }));
            }
            object propertyValue = null;
            if ((propName != null) && (propName.Length != 0))
            {
                propertyValue = GetPropertyValue(container, propName);
            }
            else
            {
                propertyValue = container;
            }
            if (propertyValue == null)
            {
                return obj2;
            }
            Array array = propertyValue as Array;
            if ((array != null) && flag)
            {
                return array.GetValue((int)obj3);
            }
            if ((propertyValue is IList) && flag)
            {
                return ((IList)propertyValue)[(int)obj3];
            }
            PropertyInfo info = propertyValue.GetType().GetProperty("Item", BindingFlags.Public | BindingFlags.Instance, null, null, new Type[] { obj3.GetType() }, null);
            if (info == null)
            {
                return null;
                //throw new ArgumentException("DataBinder_No_Indexed_Accessor");//SR.GetString("DataBinder_No_Indexed_Accessor", new object[] { propertyValue.GetType().FullName }));
            }
            return info.GetValue(propertyValue, new object[] { obj3 });
        }

        #endregion

        public static string Eval(object container, string expression, string format)
        {
            object obj2 = Eval(container, expression);
            if ((obj2 == null) || (obj2 == DBNull.Value))
            {
                return string.Empty;
            }
            if (string.IsNullOrEmpty(format))
            {
                return obj2.ToString();
            }
            return string.Format(format, obj2);
        }

        public static object Eval(object container, string expression)
        {
            if (expression == null)
            {
                //throw new ArgumentNullException("expression");
                return null;
            }
            expression = expression.Trim();
            if (expression.Length == 0)
            {
                //throw new ArgumentNullException("expression");
                return null;
            }
            if (container == null)
            {
                return null;
            }
            string[] expressionParts = expression.Split(expressionPartSeparator);
            return Eval(container, expressionParts);
        }

        public static object Eval(object container, string[] expressionParts)
        {
            object propertyValue = container;
            for (int i = 0; (i < expressionParts.Length) && (propertyValue != null); i++)
            {
                string propName = expressionParts[i];
                bool isIndexedProperty = false;
                if (propName.IndexOfAny(indexExprStartChars) >= 0)
                {
                    propName = propName.TrimStart('[').TrimEnd(']').Trim('"');
                    isIndexedProperty = true;
                }

                #region 针对特定类型做处理，加快解析速度
                if (propertyValue == null || container == null)
                {

                }
                else if (container is IDictionary)
                {
                    propertyValue = (container as IDictionary)[propName];

                }
                else if (container is IList)
                {
                    propertyValue = (container as IList)[Convert.ToInt32(propName)];

                }
                else if (container is System.Data.DataRowCollection)
                {
                    propertyValue = (container as System.Data.DataRowCollection)[Convert.ToInt32(propName)];
                }
                else if (container is System.Data.DataRow || container is System.Data.DataRowView)
                {
                    System.Data.DataRow dr;
                    if (container is System.Data.DataRowView)
                        dr = (container as System.Data.DataRowView).Row;
                    else
                        dr = container as System.Data.DataRow;

                    if (ParserRegex.Number.Match(propName).Success)
                        propertyValue = dr[Convert.ToInt32(propName)];
                    else
                        propertyValue = dr[propName];
                }
                else
                {
                    propName = expressionParts[i];
                    if (!isIndexedProperty)
                    {
                        propertyValue = GetPropertyValue(propertyValue, propName);
                    }
                    else
                    {
                        propertyValue = GetIndexedPropertyValue(propertyValue, propName);
                    }
                }
                #endregion

            }
            return propertyValue;
        }
        #region
        //public static object Eval(object container, string[] expressionParts)
        //{
        //    object propertyValue = container;
        //    for (int i = 0; (i < expressionParts.Length) && (propertyValue != null); i++)
        //    {
        //        string propName = expressionParts[i];
        //        if (propName.IndexOfAny(indexExprStartChars) < 0)
        //        {
        //            propertyValue = GetPropertyValue(propertyValue, propName);
        //        }
        //        else
        //        {
        //            propertyValue = GetIndexedPropertyValue(propertyValue, propName);
        //        }
        //    }
        //    return propertyValue;
        //}
        #endregion

        public static object GetPropertyValue(object container, string propName)
        {
            if (container == null)
            {
                return null;
                //throw new ArgumentNullException("container");
            }
            if (string.IsNullOrEmpty(propName))
            {
                return null;
                //throw new ArgumentNullException("propName");
            }
            //PropertyDescriptor descriptor = GetPropertiesFromCache(container).Find(propName, true);
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(container).Find(propName, true);
            if (descriptor == null)
            {
                return GetIndexedPropertyValue(container, string.Concat("[\"", propName, "\"]"));
                //throw new HttpException("Property Not Found");//", new object[] { container.GetType().FullName, propName })
            }
            return descriptor.GetValue(container);
        }

        //internal static PropertyDescriptorCollection GetPropertiesFromCache(object container)
        //{
        //    if (!EnableCaching || (container is ICustomTypeDescriptor))
        //    {
        //        return TypeDescriptor.GetProperties(container);
        //    }
        //    PropertyDescriptorCollection properties = null;
        //    Type key = container.GetType();
        //    if (!propertyCache.TryGetValue(key, out properties))
        //    {
        //        properties = TypeDescriptor.GetProperties(key);
        //        propertyCache.TryAdd(key, properties);
        //    }
        //    return properties;
        //}
        #endregion
        #region


        //public virtual object EvalProperty(object obj, string propertyName)
        //{
        //    try
        //    {
        //        #region 针对特定类型做处理，加快解析速度
        //        if (obj == null)
        //            return "对象未实例化";
        //        if (obj is System.Collections.Hashtable)
        //            return (obj as System.Collections.Hashtable)[propertyName];
        //        else if (obj is System.Data.DataRowCollection)
        //            return (obj as System.Data.DataRowCollection)[Convert.ToInt32(propertyName)];
        //        else if (obj is System.Data.DataRow)
        //            return ParserRegex.Number.Match(propertyName).Success ? (obj as System.Data.DataRow)[Convert.ToInt32(propertyName)] : (obj as System.Data.DataRow)[propertyName];
        //        else if (obj is System.Data.DataRowView)
        //            return ParserRegex.Number.Match(propertyName).Success ? (obj as System.Data.DataRowView).Row[Convert.ToInt32(propertyName)] : (obj as System.Data.DataRowView).Row[propertyName];
        //        else if (obj is Array)
        //            return (obj as Array).GetValue(Convert.ToInt32(propertyName));
        //        #endregion

        //        PropertyInfo pinfo = obj.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.Instance);

        //        if (pinfo != null)
        //            return pinfo.GetValue(obj, null);

        //        FieldInfo finfo = obj.GetType().GetField(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.GetField | BindingFlags.Instance);

        //        if (finfo != null)
        //            return finfo.GetValue(obj);
        //        else
        //            return "在 '" + obj.GetType().Name + "' 类型中无法找到属性名 '" + propertyName + "'.";
        //    }
        //    catch (Exception e)
        //    {
        //        return e.Message;
        //    }
        //}

        public virtual MethodInfo EvalMethod(Type obj, string methodName, Type[] args)
        {
            if (args == null)
                return obj.GetMethod(methodName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
            return obj.GetMethod(methodName,
                BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance,
                null, args, null);
        }
        public virtual object EvalMethodCall(object obj, string methodName, object[] args)
        {
            try
            {
                Type[] types = new Type[args.Length];
                for (int i = 0; i < args.Length; i++)
                    types[i] = args[i].GetType();
                MethodInfo method = EvalMethod(obj.GetType(), methodName, types);
                if (method == null)
                    return string.Format("在类型 {1} 中未找到静态方法 {0}.", methodName, obj.GetType().Name);

                return method.Invoke(obj, args);
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }

        public virtual IEnumerable ToIEnumerable(object dataSource)
        {
            if (dataSource == null)
                return null;
            if (dataSource is IListSource)
            {
                IListSource source = (IListSource)dataSource;
                IList list = source.GetList();
                if (!source.ContainsListCollection)
                {
                    return list;
                }
                if ((list != null) && (list is ITypedList))
                {
                    PropertyDescriptorCollection itemProperties = ((ITypedList)list).GetItemProperties(new PropertyDescriptor[0]);
                    if ((itemProperties == null) || (itemProperties.Count == 0))
                    {
                        return null;
                    }
                    PropertyDescriptor descriptor = itemProperties[0];
                    if (descriptor != null)
                    {
                        object component = list[0];
                        object value = descriptor.GetValue(component);
                        if ((value != null) && (value is IEnumerable))
                        {
                            return (IEnumerable)value;
                        }
                    }
                    return null;
                }
            }
            if (dataSource is IEnumerable)
            {
                return (IEnumerable)dataSource;
            }
            return null;

        }
        #endregion


        private static Dictionary<string, FuncHandler> handlers = new Dictionary<string,FuncHandler>();
        public static Dictionary<string, FuncHandler> HandlerCollection
        {
            get { return handlers; }
            set { handlers = value; }
        }

        private static List<object> cs = new List<object>();
        public static List<object> ClassCollection
        {
            get { return cs; }
            set { cs = value; }
        }
    }
}


#region

//using System;
//using System.Collections.Generic;
//using System.Reflection;
//using System.Collections;
//using System.ComponentModel;

//namespace JinianNet.JNTemplate.Process
//{
//    public class VariableScope
//    {
//        private VariableScope _parent;

//        private IDataSource _dataSource;

//        private Dictionary<string, object> _values;
//        public VariableScope()
//            : this(null)
//        {

//        }
//        public IDataSource DataSource
//        {
//            get
//            {
//                if (this._dataSource != null)
//                    return this._dataSource;
//                if (this._parent != null)
//                    return this._parent._dataSource;
//                return null;
//            }
//            set
//            {
//                this._dataSource = value;
//            }

//        }

//        public VariableScope(VariableScope parent)
//        {
//            this._parent = parent;
//            this._values = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        public void Clear()
//        {
//            Clear(false);
//        }
//        /// <summary>
//        /// 
//        /// </summary>
//        public void Clear(bool all)
//        {
//            this._values.Clear();
//            if (all)
//            {
//                if (this._parent != null)
//                {
//                    this._parent.Clear();
//                }
//            }
//        }
//        /// <summary>
//        /// 
//        /// </summary>
//        public VariableScope Parent
//        {
//            get { return this._parent; }
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        public bool IsDefined(string name)
//        {
//            if (this._values.ContainsKey(name))
//                return true;
//            else if (_parent != null)
//                return this._parent.IsDefined(name);
//            else
//                return false;
//        }
//        /// <summary>
//        /// 
//        /// </summary>
//        public object this[string name]
//        {
//            get
//            {
//                object val;
//                if (this._values.ContainsKey(name))
//                {
//                    if (this._values.TryGetValue(name, out val))
//                        return val;
//                }
//                else
//                    if (this._parent != null)
//                        return this._parent[name];
//                return null;
//            }
//            set
//            {
//                this._values[name] = value;
//            }
//        }
//        #region
//        public virtual object EvalProperty(object obj, string propertyName)
//        {

//            try {

//                #region
//                //Type t = obj.GetType();

//                //PropertyInfo pinfo = t.GetProperty(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.Instance);
//                //if (pinfo != null) {
//                //    return DynamicMethodCompiler.CreateGetHandler(t, pinfo)(obj);
//                //}
//                //FieldInfo finfo = t.GetField(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.GetField | BindingFlags.Instance);
//                //if (finfo != null) {
//                //    return DynamicMethodCompiler.CreateGetHandler(t, finfo)(obj);
//                //}
//                ////return "在 '" + t.Name + "' 类型中无法找到属性或索引 '" + propertyName + "'.";
//                //return EvalIndexProperty(t, obj, propertyName);
//                #endregion
//                #region
//                Type t = obj.GetType();

//                PropertyInfo pinfo = t.GetProperty(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.GetProperty | BindingFlags.Instance);
//                if (pinfo != null)
//                    return pinfo.GetValue(obj, null);
//                FieldInfo finfo = t.GetField(propertyName, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.GetField | BindingFlags.Instance);
//                if (finfo != null)
//                    return finfo.GetValue(obj);
//                //return "在 '" + t.Name + "' 类型中无法找到属性或索引 '" + propertyName + "'.";
//                return EvalIndexProperty(t, obj, propertyName);
//                #endregion
//            }
//            catch (Exception e) {
//                return e.Message;
//            }
//        }

//        public object EvalIndexProperty(object obj, string propertyName)
//        {
//            return EvalIndexProperty(obj.GetType(), obj, propertyName);
//        }

//        public virtual object EvalIndexProperty(Type t, object obj, string propertyName)
//        {
//            try
//            {
//                //索引属性
//                #region 针对特定类型做处理，加快解析速度
//                if (obj == null)
//                    return "对象未实例化";
//                if (obj is Array)
//                    return (obj as Array).GetValue(Convert.ToInt32(propertyName));
//                if (obj is IList && ParserRegex.Number.Match(propertyName).Success)
//                    return (obj as IList)[Convert.ToInt32(propertyName)];
//                if (obj is IListSource && ParserRegex.Number.Match(propertyName).Success)
//                    return (obj as IListSource).GetList()[Convert.ToInt32(propertyName)];
//                if (obj is System.Collections.Hashtable)
//                    return (obj as System.Collections.Hashtable)[propertyName];
//                if (obj is System.Data.DataRowCollection && ParserRegex.Number.Match(propertyName).Success)
//                    return (obj as System.Data.DataRowCollection)[Convert.ToInt32(propertyName)];
//                if (obj is System.Data.DataRow)
//                    return ParserRegex.Number.Match(propertyName).Success ? (obj as System.Data.DataRow)[Convert.ToInt32(propertyName)] : (obj as System.Data.DataRow)[propertyName];
//                if (obj is System.Data.DataRowView)
//                    return ParserRegex.Number.Match(propertyName).Success ? (obj as System.Data.DataRowView).Row[Convert.ToInt32(propertyName)] : (obj as System.Data.DataRowView).Row[propertyName];

//                #endregion

//                Type[] types = new Type[1];
//                MethodInfo mehod = null;
//                if (ParserRegex.Number.Match(propertyName).Success)
//                {
//                    types.SetValue(typeof(int), 0);
//                    mehod = t.GetMethod("get_Item", types);
//                    if (mehod != null)
//                        return mehod.Invoke(obj, new object[] { int.Parse(propertyName) });
//                }

//                types.SetValue(typeof(string), 0);
//                mehod = t.GetMethod("get_Item", types);
//                if (mehod != null)
//                    return mehod.Invoke(obj, new object[] { int.Parse(propertyName) });


//                types.SetValue(typeof(object), 0);
//                mehod = t.GetMethod("get_Item", types);
//                if (mehod != null)
//                    return mehod.Invoke(obj, new object[] { int.Parse(propertyName) });

//                return "在 '" + t.Name + "' 类型中无法找到属性或索引 '" + propertyName + "'.";
//            }
//            catch (Exception e)
//            {
//                return e.Message;
//            }

//        }


//        public virtual object EvalMethodCall(object obj, string methodName, object[] args)
//        {
//            try
//            {
//                Type[] types = new Type[args.Length];
//                for (int i = 0; i < args.Length; i++)
//                    types[i] = args[i].GetType();
//                MethodInfo method = obj.GetType().GetMethod(methodName,
//                    BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance,
//                    null, types, null);

//                if (method == null)
//                    return string.Format("在类型 {1} 中未找到静态方法 {0}.", methodName, obj.GetType().Name);

//                return method.Invoke(obj, args);
//            }
//            catch (Exception e)
//            {
//                return e.Message;
//            }
//        }

//        public virtual IEnumerable ToIEnumerable(object dataSource)
//        {
//            if (dataSource == null)
//                return null;
//            if (dataSource is IListSource)
//            {
//                IListSource source = (IListSource)dataSource;
//                IList list = source.GetList();
//                if (!source.ContainsListCollection)
//                {
//                    return list;
//                }
//                if ((list != null) && (list is ITypedList))
//                {
//                    PropertyDescriptorCollection itemProperties = ((ITypedList)list).GetItemProperties(new PropertyDescriptor[0]);
//                    if ((itemProperties == null) || (itemProperties.Count == 0))
//                    {
//                        return null;
//                    }
//                    PropertyDescriptor descriptor = itemProperties[0];
//                    if (descriptor != null)
//                    {
//                        object component = list[0];
//                        object value = descriptor.GetValue(component);
//                        if ((value != null) && (value is IEnumerable))
//                        {
//                            return (IEnumerable)value;
//                        }
//                    }
//                    return null;
//                }
//            }
//            if (dataSource is IEnumerable)
//            {
//                return (IEnumerable)dataSource;
//            }
//            return null;

//        }
//        #endregion
//    }
//}
#endregion
